#include "Serial.h"
#include "MyDMA.h" 
#include <stdarg.h>
#include <string.h>

uint8_t* Serial_RxBuf = NULL;    // 数据存出
uint16_t Serial_RxLen = 0;       // 实际长度
uint8_t Serial_RxFlag = 0;       // 接收完成的标志
uint16_t SERIAL_RX_BUF_LEN = 0;  // 缓存总长度


void Serial_Init(void)  
{
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
	
    // TX:PA9 复用推挽输出
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
	
    // RX:PA10 浮空输入
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600;                  // 波特率9600bps
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无流控
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //
    USART_InitStructure.USART_Parity = USART_Parity_No;          // 无校验
    USART_InitStructure.USART_StopBits = USART_StopBits_1;       // 1位停止位
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;  // 8位数据位
    USART_Init(USART1, &USART_InitStructure);
    
    // UART1空闲中断
    USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); 
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    // 初始化MyDMA并绑定缓存
    USART_Cmd(USART1, ENABLE);         
    MyDMA_UART1_Init();                 
    Serial_RxBuf = MyDMA_UART1_GetRxBuf(); // 将数据存在DMA
    SERIAL_RX_BUF_LEN = MyDMA_UART1_GetRxBufLen(); // 从MyDMA获取缓存长度
}

// UART1中断函数（关键）
void USART1_IRQHandler(void)
{
	//判断是否是空闲中断
    if (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
    {
        USART_ReceiveData(USART1); // 清标志
        USART_ClearITPendingBit(USART1, USART_IT_IDLE);
        
        // 计算接收长度，缓存总长度-还没用到的长度=实际长度
        Serial_RxLen = SERIAL_RX_BUF_LEN - MyDMA_UART1_GetRxRemain();
        Serial_RxFlag = 1; //告诉主函数可以读数据了
        
        MyDMA_UART1_RestartRx(); // 重启接收
    }
}


//下面是串口发送的相关代码
//发送字节
void Serial_SendByte(uint8_t Byte)
{
    USART_SendData(USART1, Byte);
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

//发送数组
void Serial_SendArray(uint8_t *Array, uint16_t Length)
{
    for (uint16_t i = 0; i < Length; i++)
    {
        Serial_SendByte(Array[i]);
    }
}


void Serial_SendString(char *String)
{
    for (uint16_t i = 0; String[i] != '\0'; i++)
    {
        Serial_SendByte(String[i]);
    }
}


uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
	uint32_t Result = 1;	//设置结果初值为1
	while (Y --)			//执行Y次
	{
		Result *= X;		//将X累乘到结果
	}
	return Result;
}

void Serial_SendNumber(uint32_t Number, uint8_t Length)
{
    for (uint8_t i = 0; i < Length; i++)
    {
        uint8_t Digit = Number / Serial_Pow(10, Length - i - 1) % 10;
        Serial_SendByte(Digit + '0');
    }
}


int fputc(int ch, FILE *f)
{
    Serial_SendByte(ch);
    return ch;
}

void Serial_Printf(char *format, ...)
{
    char String[100];
    va_list arg;
    va_start(arg, format);
    vsprintf(String, format, arg);
    va_end(arg);
    Serial_SendString(String);
}


